/**
 * 文件上传、图片上传控件，基于WebUploader扩展
 * @author bob 2016-09-12
 */
(function($){
	var DEFAULT_CHUNK_SIZE = 5 * 1024 * 1024;
	//生成uuid
	var genUuid = function(len, radix) {
		  var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
		  var uuid = [], i;
		  radix = radix || chars.length;
		 
		  if (len) {
		   // Compact form
		   for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix];
		  } else {
		   // rfc4122, version 4 form
		   var r;
		 
		   // rfc4122 requires these characters
		   uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
		   uuid[14] = '4';
		 
		   // Fill in random data. At i==19 set the high bits of clock sequence as
		   // per rfc4122, sec. 4.1.5
		   for (i = 0; i < 36; i++) {
		    if (!uuid[i]) {
		     r = 0 | Math.random()*16;
		     uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
		    }
		   }
		  }
		 
		  return uuid.join('');
	};
	
	var LANG = {
		"zh_CN":{
			pickerTitle:"选择文件",
			uploadTitle:"开始上传",
			attentionTitle:"[注：添加附件时，可用Ctrl或Shift+鼠标左键来选择多个文件]",
			waitForUploadTitle:"等待上传",
			uploadedTitle:"已上传成功",
			uploadErrorTitle:"上传失败："
		},
		"zh_TW":{
			pickerTitle:"選擇檔案",
			uploadTitle:"開始上傳",
			attentionTitle:"[注：添加附件時，可用Ctrl或Shift+滑鼠左鍵來選擇多個檔案]",
			waitForUploadTitle:"等待上傳",
			uploadedTitle:"已上傳成功",
			uploadErrorTitle:"上傳失敗："
		},
		"en":{
			pickerTitle:"Select file",
			uploadTitle:"Start upload",
			attentionTitle:"[Note: add attachments, use Ctrl or Shift+ the left mouse button to select multiple files]",
			waitForUploadTitle: "Waiting for upload",
			uploadTitle: "Uploaded successfully",
			uploadErrorTitle: "Upload failed:"
		}
	};
	
	var getUploadTpl = function(uuid, opt) {
		var lang = opt.language;
		//文件上传模板
		var uploadTpl = [
			'<div class="file_upload_div" style="display:', opt.readonly?'none':'block',';">','<div class="es_file_upload_button">',
			'<div id="file_picker_', uuid, '" >', LANG[lang].pickerTitle, '</div>',
			'<button class="webuploader-pick es_file_upload_bt_1" id="file_upload_', uuid, '"',
			'  type="button">',  LANG[lang].uploadTitle, '</button>',
			'<span class="es_file_upload_bt_2">',LANG[lang].attentionTitle ,'</span>',
			'</div>',
			'<div id="file_queue_', uuid, '" class="es_file_upload_queue"></div>','</div>'
		];
		return uploadTpl.join("");
	};
	
	
	//初始化控件
	var init = function(jq, opt) {
		var opts = getCommonOpt(jq, opt);
		var uuid = genUuid(8, 16);
		$(jq).html(getUploadTpl(uuid, opts));
		var uploader = WebUploader.create({
			// swf文件路径
			swf:opts.swfUrl,
			// 文件接收服务端。
			server:opts.uploadUrl,
			// 选择文件的按钮。可选。
			// 内部根据当前运行是创建，可能是input元素，也可能是flash.
			pick : {"id":'#file_picker_' + uuid,"multiple":opts.multiple},
			chunked: opts.chunked,  //分片处理
            chunkSize: DEFAULT_CHUNK_SIZE, //每片5M  
            threads:3,//上传并发数。允许同时最大上传进程数。
			// 不压缩image, 默认如果是jpeg，文件上传前会压缩一把再上传！
			resize : false,
			sendAsBinary:true,
			fileNumLimit:opts.maxFileNum,
			fileSizeLimit:opts.maxFileSize,
			fileSingleSizeLimit:opts.maxSingleFileSize
		});

		var lang = LANG[opts.language];
		var uuidMap = {};
		// 当有文件被添加进队列的时候
		uploader.on('fileQueued', function(file) {
			var val = $.fn.filebox.methods["getValue"](jq);
		    if(!val) {
		    	val = getAttachId(opts);
		    	$.fn.filebox.methods["setValue"](jq, val);
		    	if(opts["onFirstSelect"]) opts["onFirstSelect"].call(jq, val);
		    }
			$("#file_queue_" + uuid).append(
					['<div id="file_item_' , file.id , '" class="es_file_item">'
					        , '<div style="width:80%;display:inline-block;">', '<div>'
							, '<span class="info">' , file.name , '&nbsp;&nbsp;</span>'
							, '<span class="state">' , lang["waitForUploadTitle"] , '</span>'
							, '</div>'
							, '<div class="es-progressbar" style="width:92%;"></div>'
							, '</div>', '<div style="display:inline-block;"><a href="javascript:;" class="es_file_item_remove">x</a></div>', 
							'</div>'
							].join(""));
			var fiId = "#file_item_" + file.id;
			$(fiId).find("div.es-progressbar").progressbar({value:0, height:12});
			$(fiId).find(".es_file_item_remove").click(function(event) {
				uploader.removeFile(file, true);
				$(fiId).remove();
			});
		});

		uploader.on('uploadProgress', function(file, percentage) {
			$('#file_item_' + file.id).find('div.es-progressbar').progressbar('setValue', Math.floor(percentage*100));
		});
		
		uploader.on('uploadStart', function(file) {
			/*var formData = uploader.option("formData");
			if(!formData["uuidMap"]) {
				formData["uuidMap"] = {};
			}*/
			var uuid = genUuid(8, 16);
			uuidMap[file.id] = uuid;
			//formData["uuidMap"][file.id] = uuid;
			//formData["uuid"] = uuid;
		});
		
		uploader.on('uploadBeforeSend', function(object, data, headers) {
			data.id = "";
			var file = object.file;
			data.uuid = uuidMap[file.id];//uploader.option("formData")["uuidMap"][file.id];//修复并发上传时，文件被覆盖bug
			//console.log(data);
			//console.log(uuidMap);
		});
		
		uploader.on('uploadSuccess', function(file, response) {
			$('#file_item_' + file.id).find('span.state').text(lang["uploadedTitle"]);
			mergeFile(jq, file, uuidMap, function(data) {
				$('#file_item_' + file.id).fadeOut();
			});
		});

		uploader.on('uploadError', function(file, reason) {
			$('#file_item_' + file.id).find('span.state').text(lang["uploadErrorTitle"] + reason);
			uploader.cancelFile(file);
	        uploader.removeFile(file,true);
	        uploader.reset();
		});

		uploader.on('uploadComplete', function(file) {
			$('#file_item_' + file.id).find('div.es-progressbar').fadeOut();
		});
		
		uploader.on('uploadFinished', function() {
			var val = $.fn.filebox.methods["getValue"](jq);
			var oldVal = opts.value;
			uuidMap = {};
			if(opts["onAfterUploadFinished"]) opts["onAfterUploadFinished"].call(jq, val, oldVal, uploader.getFiles());
		});

		$("#file_upload_" + uuid).on('click', function() {
			if ($(this).hasClass('disabled')) {
				return false;
			}
			uploader.upload();
		});
		//初始化值
		if(opts.value) {
			$.fn.filebox.methods["setValue"](jq, opts.value);
		}
		$(jq).data("uploader", uploader);
	};
	
	var getCommonOpt = function(jq, opt) {
		opt.uploadUrl = opt.baseUrl + opt.uploadUrl;
		opt.queryUrl = opt.baseUrl + opt.queryUrl;
		opt.deleteUrl = opt.baseUrl + opt.deleteUrl;
		opt.downloadUrl = opt.baseUrl + opt.downloadUrl;
		opt.attachUrl = opt.baseUrl + opt.attachUrl;
		opt.swfUrl = opt.baseUrl + opt.swfUrl;
		opt.mergeUrl = opt.baseUrl + opt.mergeUrl;
	    return opt;
	};
	
	var getAttachId = function(opt) {
		var val = "";
		var options = {
				url : opt.attachUrl,
				async: false,
				success : function(data) {
					val = data.msg;
				}
		};
		fnFormAjaxWithJson(options);
		return val;
	};
	
	var mergeFile = function(jq, file, uuidMap, onAfterMerge) {
		var opt = $.fn.filebox.methods["options"](jq);
		var uploader = $(jq).data("uploader");
		var options = {
				url : opt.mergeUrl,
				data : {
					"uuid": uuidMap[file.id],//uploader.option("formData")["uuidMap"][file.id],
					"attachId": $.fn.filebox.methods["getValue"](jq),
					chunks: Math.ceil(file.size/DEFAULT_CHUNK_SIZE),
					filedataFileName: file.name,
				},
				success : function(data) {
					if(onAfterMerge) {
						onAfterMerge.call(jq, data);
					}
				}
		};
		fnFormAjaxWithJson(options);
	};
	
	$.fn.filebox = function(options, param) {
		if (typeof options == 'string') {
			var method = $.fn.filebox.methods[options];
			if (method) {
				return method(this, param);
			} else {
				return $(this).fileinput(options, param);//调用原生方法
			}
		}
		options = options || {};
		return this.each(function() {
			var state = $(this).data('filebox');
			if (state) {
				$.extend(state.options, options);
			} else {
				var opts = $.extend({}, $.fn.filebox.defaults, options);
				$(this).data('filebox', {
					options : opts,
					data : null
				});
				init(this, opts);
			}
		});
	};

	$.fn.filebox.methods = {
		options : function(jq) {
			return $(jq).data("filebox").options;
		},
		getValue : function(jq) {
			return $(jq).data("filebox").data;
		},
		setValue : function(jq, val) {
			var stateData = $(jq).data("filebox");
			if(stateData && stateData.data != val) {//只有值变更时才需要更新数据
				stateData.data = val;
			}
		},
		enable : function(jq){
			return jq.each(function() {
				$(this).find("div.file_upload_div").show();
			});
		},
		disable : function(jq){
			return jq.each(function() {
				$(this).find("div.file_upload_div").hide();
			});
		},
		destroy: function(jq){
			return jq.each(function() {
				$(this).find("div.file_upload_div").remove();
			});
		}
	};

	$.fn.filebox.defaults = $.extend({}, {
		language:"zh_CN",
		readonly:false,//文件只读，不可上传
		multiple:true, //上传多个文件
		baseUrl:"",//上下文路径
		isImage:false,//是否图片控件
		chunked: true, //默认分片
		isSimpleMode:false,//是否简单文件上传模式，不作为附件上传
		canDelete:true, //是否可以删除,readonly=true,不能删除；readonly=false，判断能否删除；
		canDownload:true, //是否可以下载
		swfUrl:"/js/webuploader/Uploader.swf",
		uploadUrl:"/sys/attach/upload-file!saveFile.action",
		mergeUrl:"/sys/attach/upload-file!mergeFile.action",
		queryUrl:"/sys/attach/attach!queryList.action",
		deleteUrl:"/sys/attach/attach!delete.action",
		downloadUrl:"/sys/attach/upload-file!downloadFile.action",
		attachUrl:"/sys/attach/attach!save.action",//获取附件ID url
		formData:{},//表单请求参数
		maxFileNum:10,//文件数量限制
		maxFileSize:500 * 1024 * 1024,//文件总大小限制，默认500M
		maxSingleFileSize: 50 * 1024 * 1024, //单文件大小限制，默认50M
		onFirstSelect:null,//第一次上传时调用
		onAfterUploadFinished:null //所有文件上传结束后调用方法
	});
})(jQuery);